// PropertiesDlg.cpp : implementation file
//

#include "stdafx.h"
#include "dq9.h"
#include "PropertiesDlg.h"
#include "DeclareList.h"
#include "PersistenceController.h"
#include "PropertyTemplate.h"
#include "EditItemPanel.h"
#include "EventManagerSngl.h"
#include "PropertyPage.h"
#include "PropertyPageFactory.h"
#include "EventCodes.h"

#include <utility/Event.h>

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif //_DEBUG
#endif //WIND32


// PropertiesDlg dialog

namespace serika
{
	namespace dq
	{
		bool PropertiesDlg::sClose = false;

		IMPLEMENT_DYNAMIC(PropertiesDlg, CDialog)

		PropertiesDlg::PropertiesDlg(CWnd* pParent /*=NULL*/)
			: CDialog(PropertiesDlg::IDD, pParent)
			, mActivePage(0)
		{
		}

		PropertiesDlg::~PropertiesDlg()
		{
		}

		// static
		PropertiesDlg*& PropertiesDlg::Instance()
		{
			static PropertiesDlg* dlg = 0;
			if (!dlg && !sClose)
			{
				dlg = new PropertiesDlg();
				dlg->Create(PropertiesDlg::IDD);
			}
			return dlg;
		}

		//static
		void PropertiesDlg::Show(CWnd* wnd)
		{
			PropertiesDlg* dlg = PropertiesDlg::Instance();
			EventManager::AttachLogicEventHandler(dlg);

			CRect rect;
			wnd->GetWindowRect(&rect);
			dlg->SetWindowPos(0, rect.right + 100, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

			dlg->ShowWindow(SW_SHOW);
		}

		//static
		void PropertiesDlg::Hide()
		{
			PropertiesDlg* dlg = PropertiesDlg::Instance();
			if (dlg)
			{
				dlg->ShowWindow(SW_HIDE);
				EventManager::DetachLogicEventHandler(dlg);
			}
		}

		//static
		void PropertiesDlg::Destroy()
		{
			PropertiesDlg* dlg = PropertiesDlg::Instance();
			if (dlg)
			{
				dlg->DestroyWindow();
			}
		}

		void PropertiesDlg::Handle(const ut::Event& e)
		{
			switch (e.GetCode())
			{
			case LEC::PropertyTemplates:
				this->OnPropertyTemplates(e);
				break;
			}
		}

		void PropertiesDlg::OnPropertyTemplates(const ut::Event& e)
		{
			//if (!mPages.empty())
			//{
			//	return;
			//}
			this->ClearPages();

			const PropertyTemplates& tmpls = *e.GetUserData<PropertyTemplates>();
			if (tmpls.empty())
			{
				return;
			}

			int index = 0;
			for (PropertyTemplates::const_iterator itr = tmpls.begin();
				itr != tmpls.end(); ++itr)
			{
				PropertyTemplate* tmpl = (*itr);
				const ut::String& name = tmpl->GetName();
				mList.InsertString(index++, name.c_str());
				this->CreatePage(tmpl);
			}

			mActivePage = mPages[0];
			mActivePage->Active();
		}

		void PropertiesDlg::DoDataExchange(CDataExchange* pDX)
		{
			CDialog::DoDataExchange(pDX);
		}

		BOOL PropertiesDlg::OnInitDialog()
		{
			CDialog::OnInitDialog();

			EventManager::AttachLogicEventHandler(this);

			this->MoveWindow(0, 0, 400, 300);
			this->CenterWindow();
			mList.SubclassDlgItem(IDC_PROPERTIES_LIST, this);
			mList.MoveWindow(0, 0, 100, 300);

			CWnd* btn = this->GetDlgItem(IDC_ADD_BTN);
			CRect clientRect;
			this->GetClientRect(&clientRect);
			CRect rect;
			btn->GetClientRect(&rect);
			btn->SetWindowPos(0, clientRect.right-rect.Width(), clientRect.bottom-rect.Height(), 0, 0, SWP_NOSIZE | SWP_NOZORDER);
			btn->ShowWindow(SW_SHOW);
			return TRUE;
		}

		BEGIN_MESSAGE_MAP(PropertiesDlg, CDialog)
			ON_LBN_SELCHANGE(IDC_PROPERTIES_LIST, OnListChanged)
			ON_WM_DESTROY()
			ON_BN_CLICKED(IDC_ADD_BTN, OnAddBtnClicked)
		END_MESSAGE_MAP()

		// PropertiesDlg message handlers
		void PropertiesDlg::OnListChanged()
		{
			mActivePage->Deactive();
			int index = mList.GetCurSel();
			mActivePage = mPages[index];
			mActivePage->Active();
		}

		void PropertiesDlg::OnDestroy()
		{
			EventManager::DetachLogicEventHandler(this);

			this->ClearPages();

			delete this;
			PropertiesDlg::sClose = true;
			PropertiesDlg::Instance() = 0;
		}

		void PropertiesDlg::OnAddBtnClicked()
		{
			Property* p = mActivePage->CreateProperty();
			ut::Event* e = ut::Event::NewEvent(ut::EventType::UI, UEC::ItemProperty);
			e->SetUserData(p);
			EventManager::SendEvent(e);
		}

		void PropertiesDlg::ClearPages()
		{
			mList.ResetContent();

			for (Pages::iterator itr = mPages.begin(); itr != mPages.end(); ++itr)
			{
				PropertyPage* page = *itr;
				if (page)
				{
					page->DestroyWindow();
					delete page;
				}
			}
			mPages.erase(mPages.begin(), mPages.end());
		}

		void PropertiesDlg::CreatePage(PropertyTemplate* tmpl)
		{
			PropertyPage* page = PropertyPageFactory::CreatePage(tmpl);
			page->Create(this);
			mPages.push_back(page);
		}

		void PropertiesDlg::Activate()
		{
			EventManager::AttachLogicEventHandler(this);
			this->ShowWindow(SW_SHOW);
		}

		void PropertiesDlg::Deactivate()
		{
			this->ShowWindow(SW_HIDE);
			EventManager::DetachLogicEventHandler(this);
		}
	}
}

